using System;
using System.Collections.Generic;
using System.Text;
using Juego.Puente;
using Juego;
using System.Windows.Forms;
using PuenteInterfase;
using System.Diagnostics;
using System.Threading;

namespace Juego.Controlador
{
    public class ControladorJuego : IJuego
    {
        private Juego _juego;
        private IList<BloqueaTocar> _listaBloquesEnJuego;
        private Queue<BloqueaTocar> _bloquesPorLlegar;
        private double _tiempocero;
        private bool _estaenejecucion;
        private IList<BloqueaTocar> _bloquesABorrar;
        private IDictionary<int, BloqueaTocar> _bloqueslocos;

        public event DelAlAgregarseUnBloque AlAgregarseUnBloque;
        public event DelAlMoverseUnBloque AlMoverseUnBloque;
        public event DelAlBorrarseUnBloque AlBorrarseUnBloque;
		public event DelAlPresionarBienLaCuerda AlPresionarBienLaCuerda;
		public event DelAlPresionarMalLaCuerda AlPresionarMalLaCuerda;

        public ControladorJuego(Juego juego)
        {
            _juego = juego;
            _estaenejecucion = false;
        }

        private double AhoraEnSegundos()
        {
            return (System.DateTime.Now.TimeOfDay.TotalMilliseconds);
        }

        public bool QuedanBloquesEnJuego
        {
            get { return this._listaBloquesEnJuego.Count > 0; }
        }

        public IList<BloqueaTocar> BloquesEnJuego
        {
            get { return this._listaBloquesEnJuego; }
        }

        public IDictionary<int, BloqueaTocar> BloquesVisibles
        {
            get { return this._bloqueslocos; }
        }

        public void Jugar()
        {
            _bloquesABorrar = new List<BloqueaTocar>();
            _tiempocero = AhoraEnSegundos();
            _listaBloquesEnJuego = new List<BloqueaTocar>();
            _bloquesPorLlegar = this._juego.BloquesPorLlegar;
            _estaenejecucion = true;
            _bloqueslocos = new Dictionary<int, BloqueaTocar>();

            do
            {
                Dibujar();
                Simular();
                //Thread.Sleep(TimeSpan.FromMilliseconds(20));
                //if ((_bloquesPorLlegar.Count == 0) || (_listaBloquesEnJuego.Count == 0))
                  //  _estaenejecucion = false;
                
            } while (_estaenejecucion);
            
        }

        public void Simular()
        {
            if (this.QuedanBloquesEnJuego || _bloquesPorLlegar.Count > 0)
                _estaenejecucion = true;
            else
                _estaenejecucion = false;

        }

        public void Dibujar()
        {
            
            if (this.QuedanBloquesEnJuego || _bloquesPorLlegar.Count > 0)
            {

                double justoAhora = this.AhoraEnSegundos();
                
                if (_bloquesPorLlegar.Count > 0)
                {
                    BloqueaTocar b = _bloquesPorLlegar.Peek();

                    if (((b.TiempoASerLanzado * 1000) + _tiempocero) < justoAhora)
                    {
                        BloqueaTocar bloque = _bloquesPorLlegar.Dequeue();
                        bloque.MomentoFueSoltado = (bloque.TiempoASerLanzado * 1000) + _tiempocero;
                        Debug.WriteLine("Desencole " + b.TiempoASerLanzado.ToString() + " + " + _tiempocero.ToString() + "<" + justoAhora.ToString());

                        _bloqueslocos.Add(bloque.Id, bloque);

                        _listaBloquesEnJuego.Add(bloque);
                        AlAgregarseUnBloque(bloque);
                    }

                }

                IEnumerator<BloqueaTocar> iteradorBloquesEnJuego = _listaBloquesEnJuego.GetEnumerator();
                
                while (iteradorBloquesEnJuego.MoveNext())
                {
                    // calcular cuan "abajo" esta
                    double t = justoAhora - iteradorBloquesEnJuego.Current.MomentoFueSoltado;
                    double v = 100;
                    
                    iteradorBloquesEnJuego.Current.PosicionY = (t * v) / 1000;
                    _bloqueslocos[iteradorBloquesEnJuego.Current.Id].PosicionY = (t * v) / 1000;

                    AlMoverseUnBloque(iteradorBloquesEnJuego.Current);

                    if (iteradorBloquesEnJuego.Current.PosicionY > 250)
                        _bloquesABorrar.Add(iteradorBloquesEnJuego.Current);
                    

                    //Debug.WriteLine("el bloque esta en la posicion " + bloque.PosicionY);
                }
                iteradorBloquesEnJuego.Dispose();

                foreach (BloqueaTocar bloque in _bloquesABorrar)
                {
                    _listaBloquesEnJuego.Remove(bloque);
                    AlBorrarseUnBloque(bloque);

                }

                _bloquesABorrar.Clear();

            }
        }

		public void CambioElPuntaje(int puntos)
		{
			AlPresionarBienLaCuerda(puntos);
		}

		public void PresionoMal()
		{
			//if (AlPresionarMalLaCuerda != null)
				AlPresionarMalLaCuerda();
		}
    }

}